package com.share.example.stock.schedule;

import com.alibaba.fastjson.JSON;
import com.share.common.utils.CollectionUtil;
import com.share.common.utils.DateExtUtil;
import com.share.common.utils.DateUtil;
import com.share.example.stock.model.db.ScheduleLog;
import com.share.example.stock.model.db.StockDayPrice;
import com.share.example.stock.service.IScheduleLogService;
import com.share.example.stock.service.IStockBaseInfoService;
import com.share.example.stock.service.IStockDayPriceService;
import com.share.example.stock.service.ITradeDateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

/**
 * 日数据下载
 */
@Slf4j
@Component
public class S12_Down_stock_day {
    private String className = this.getClass().getSimpleName();
    @Autowired
    private IScheduleLogService iScheduleLogService;

    @Autowired
    private IStockBaseInfoService iStockBaseInfoService;
    @Autowired
    private IStockDayPriceService iStockDayPriceService;

    @Autowired
    private ITradeDateService iTradeDateService;

    //收盘盘结束-到当天23点
    @Scheduled(cron = "0 8/20 9-16,23 * * ?")
    public void dowm_stock_today() {
        Date date = new Date();
        //对时间再次细分
        int intDate = DateExtUtil.getTimeInt(date);
        if ((intDate > 93100 && intDate < 115000) || (intDate > 130500 && intDate < 152000) || (intDate > 230000 && intDate < 232500)) {
            //可以使用的时间
        } else {
            log.info("不满足时间直接退出");
            return;
        }

        //周日直接跳过
        if (!iTradeDateService.isTradeDay(new Date())) {
            log.info("非交易日直接退出");
            return;
        }

        String jobCode = className + "_" + "dowm_stock_today";

        //开始日志
        ScheduleLog insertLog = iScheduleLogService.insertLog(jobCode);

        //开始下载数据库
        ScheduleLog upLog = new ScheduleLog().setId(insertLog.getId());
        try {
            List<StockDayPrice> list = iStockDayPriceService.downToDay();
            upLog.setStatus("1");
            upLog.setRemark("数据条数=" + (list == null ? 0 : list.size()));
        } catch (Exception e) {
            upLog.setExpMsg(e.getMessage());
            log.error("下载失败", e);
        }

        //更新日志
        iScheduleLogService.updateLogById(upLog);
    }

    //任意时间---这个获取的是昨天的数据------只需要通过同步一次---以后按照增量去取
    @Scheduled(cron = "58 */15 * * * ?")
    public void dowm_stock_day_hist() {
        String jobCode = className + "_" + "dowm_stock_day_hist";
        List<String> codeList = iStockBaseInfoService.listCodeByDayPullCount();
        if (CollectionUtils.isEmpty(codeList)) {
            return;
        }

        //开始日志
        ScheduleLog insertLog = iScheduleLogService.insertLog(jobCode);

        //开始下载数据库
        ScheduleLog upLog = new ScheduleLog().setId(insertLog.getId());
        try {

            int threadNum = 5;
            if ((codeList.size() / 10) < 0) {
                threadNum = 1;
            }
            CountDownLatch countDownLatch = new CountDownLatch(threadNum);
            List<List<String>> partitionList = CollectionUtil.splitByThreadNum(codeList, threadNum);
            for (List<String> tmpList : partitionList) {
                //开启新的线程
                new Thread(() -> {
                    List<StockDayPrice> stockDayPrices = iStockDayPriceService.downDayHist(tmpList, null, null);
                    countDownLatch.countDown();
                }).start();
            }

            //等待
            countDownLatch.await();

            upLog.setStatus("1");
            upLog.setRemark("code条数=" + codeList.size());
        } catch (Exception e) {
            upLog.setExpMsg(e.getMessage());
            log.error("下载失败", e);
        }

        //更新日志
        iScheduleLogService.updateLogById(upLog);
    }


    //每天一点,开始检测数据是否缺失，如果缺失则修改该票为待拉取状态,必须设置在1点
    @Scheduled(cron = "58 1 1,5 * * ?")
    public void dowm_stock_check_day_his() {
        //周日直接跳过
        Date date = new Date();
        if (!iTradeDateService.isTradeDay(date)) {
            log.info("非交易日直接退出");
            return;
        }

        String endDate = iTradeDateService.getYesterday(DateUtil.getDate(date));
        String startDate = DateUtil.getDate(date, -30);

        String jobCode = className + "_" + "dowm_stock_data_check_his";

        //开始日志
        ScheduleLog insertLog = iScheduleLogService.insertLog(jobCode);

        ScheduleLog upLog = new ScheduleLog().setId(insertLog.getId());
        try {
            Map<String, List<String>> codeMap = iStockDayPriceService.checkDayHis(startDate, endDate);

            upLog.setStatus("1");
            upLog.setRemark("codeMap=" + JSON.toJSON(codeMap));
        } catch (Exception e) {
            upLog.setExpMsg(e.getMessage());
            log.error("下载失败", e);
        }

        //更新日志
        iScheduleLogService.updateLogById(upLog);
    }
}
